﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Devmil.MVVM.Dependencies
{
    public static class NotifyDependencyCache
    {
        private static List<NotifyDependencyPath> cache = new List<NotifyDependencyPath>();

        public static IEnumerable<NotifyDependencyPath> Content
        {
            get
            {
                return cache.AsEnumerable();
            }
        }

        public static void AddPath(NotifyDependencyPath path)
        {
            lock (cache)
                if (!cache.Contains(path))
                    cache.Add(path);
        }

        public static void CleanUp()
        {
            lock (cache)
            {
                List<int> indicesToRemove = new List<int>();
                for (int i = 0; i < cache.Count; i++)
                    if (!cache[i].IsAlive)
                        indicesToRemove.Add(i);
                for (int i = indicesToRemove.Count - 1; i >= 0; i--)
                    cache.RemoveAt(indicesToRemove[i]);
            }
        }

        public static IEnumerable<NotifyDependencyPath> GetDependetPaths(object editedObject, string propertyName)
        {
            lock (cache)
            {
                CleanUp();
                return cache.Where(p => p.Target == editedObject && p.TargetPropertyName == propertyName);
            }
        }

        public static IEnumerable<KeyValuePair<object, string>> GetDependentPropertyChanges(object editedObject, string propertyName)
        {
            lock (cache)
            {
                return GetDependetPaths(editedObject, propertyName)
                    .SelectMany(p => p.Nodes)
                    .Where(n => n.IsAlive)
                    .Select(n => new KeyValuePair<object, string>(n.GetterTargetObject.Target, n.PropertyName))
                    .Distinct().ToList();
            }
        }
    }
}
